package com.chagee.store.operation.server.config;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape;
import com.baomidou.mybatisplus.extension.plugins.handler.DataPermissionHandler;
import com.chagee.personnel.api.event.auth.UserAuthInfo;
import com.chagee.personnel.api.event.enums.UserAuthTypeEnum;
import com.chagee.store.operation.common.exception.BizErrorCode;
import com.chagee.store.operation.common.exception.BizException;
import com.chagee.store.operation.server.utils.MybatisTenantContext;
import com.chagee.store.operation.server.utils.SqlThreadLocalUtil;
import com.chagee.store.operation.server.utils.UserUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.FromItem;
import net.sf.jsqlparser.statement.select.PlainSelect;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author yangyang
 * @date 2024/3/14-11:49
 **/
@Slf4j
public class DataPermissionImplHandler implements DataPermissionHandler {

	@Override
	public Expression getSqlSegment(Expression where, String mappedStatementId) {
		log.info("getSqlSegment() called with parameters => 【where = {}】, 【mappedStatementId = {}】",where, mappedStatementId);
		UserAuthInfo user = UserUtil.getUser();
		UserAuthTypeEnum userAuthTypeEnum = user.getUserAuthTypeEnum();
		if (userAuthTypeEnum==UserAuthTypeEnum.ALL){
			return null;
		}
		boolean b = MybatisTenantContext.get() == null || MybatisTenantContext.get();
		log.info("DataPermissionImplHandler.getSqlSegment(),=> 【{}】,=>【{}】",b,user);
		if (!b && (!StrUtil.isBlankIfStr(user.getUserId()) || CollUtil.isNotEmpty(user.getDeptIds()))) {
			log.info("开始处理数据权限sql");
			String sqlSegment = "";
			Map<String, PlainSelect> map = SqlThreadLocalUtil.get();
			PlainSelect plainSelect = map.get(mappedStatementId);
			FromItem fromItem =  plainSelect.getFromItem();
			boolean haveCreateUser = false;
			if (!StrUtil.isBlankIfStr(user.getUserId())) {
				haveCreateUser = true;
				if (fromItem instanceof Table) {
					Table table = (Table) fromItem;
					String tableName = table.getName();
					String tableAlias = table.getAlias() != null ? table.getAlias().getName() : "";
					if (StrUtil.isNotEmpty(tableAlias)) {
						sqlSegment = sqlSegment + tableAlias+".create_user = '" + StringEscape.escapeRawString(String.valueOf(user.getUserId()))+"'";
					}else {
						sqlSegment = sqlSegment + "create_user = '" + StringEscape.escapeRawString(String.valueOf(user.getUserId()))+"'";
					}
				}else {
					sqlSegment = sqlSegment + "create_user = '" + StringEscape.escapeRawString(String.valueOf(user.getUserId()))+"'";
				}

			/*	if (plainSelect.getJoins() != null) {
					for (Join join : plainSelect.getJoins()) {
						if (join.getRightItem() instanceof Table) {
							Table table = (Table) join.getRightItem();
							String tableName = table.getName();
							String tableAlias = table.getAlias() != null ? table.getAlias().getName() : "";
							System.out.println("Table: " + tableName + ", Alias: " + tableAlias);
						}
					}
				}*/
			}
			if (CollUtil.isNotEmpty(user.getDeptIds())) {
				if (haveCreateUser) {
					sqlSegment = sqlSegment + " and ";
				}
				List<String> list = Collections.singletonList(String.valueOf(user.getDeptIds()));
				if (fromItem instanceof Table) {
					Table table = (Table) fromItem;
					String tableName = table.getName();
					String tableAlias = table.getAlias() != null ? table.getAlias().getName() : "";
					if (StrUtil.isNotEmpty(tableAlias)) {
						sqlSegment = sqlSegment + tableAlias+ ".create_dept IN ('" + String.join("', '", list) + "')";
					}else {
						sqlSegment = sqlSegment + "create_dept IN ('" + String.join("', '", list) + "')";
					}
				}else {
					sqlSegment = sqlSegment + "create_dept IN ('" + String.join("', '", list) + "')";
				}
				sqlSegment = sqlSegment.replace("[", "").replace("]", "");
			}
			try {
				log.info("CCJSqlParserUtil.parseCondExpression.sqlSegment sql : [{}]", sqlSegment);
				Expression sqlSegmentExpression = CCJSqlParserUtil.parseCondExpression(sqlSegment);
				log.info("CCJSqlParserUtil.parseCondExpression.sqlSegment success sql : [{}]", sqlSegment);
				if (null != where) {
					log.info("原 where =>【{}】", where);
					if (mappedStatementId.equals("TEST_4")) {
						// 这里测试返回 OR 条件
						return new OrExpression(where, sqlSegmentExpression);
					}
					return new AndExpression(where, sqlSegmentExpression);
				}
				return sqlSegmentExpression;
			} catch (JSQLParserException e) {
				log.error("getSqlSegment() called with exception => 【where = {}】, 【mappedStatementId = {}】", where, mappedStatementId, e);
				throw new BizException(BizErrorCode.FAIL.getErrorCode(), BizErrorCode.FAIL.getErrorMsg());
			}finally {
				SqlThreadLocalUtil.remove();
			}
		}
		return null;
	}
}
